package com.yc.services;

import com.alibaba.nacos.common.utils.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yc.bean.OrderItems;
import com.yc.bean.Orders;
import com.yc.mapper.OrderItemsMapper;
import com.yc.mapper.OrdersMapper;
import com.yc.web.DTO.OrderItemsDTO;
import com.yc.web.DTO.OrdersDTO;
import com.yc.web.clients.IdGeneratorClient;
import com.yc.web.controller.model.ResponseResult;
import lombok.AllArgsConstructor;
import lombok.extern.java.Log;
import org.springframework.beans.BeanUtils;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@AllArgsConstructor
@Log
public class OrdersServiceImpl implements OrdersService {

    private final OrdersMapper ordersMapper;
    private final OrderItemsMapper orderItemsMapper;
    private final IdGeneratorClient idGeneratorClient;
    private final OrderItemsService orderItemsService;

    /**
     * 创建订单
     * @param ordersDTO
     * @return
     */
    @Override
    @Transactional
    public OrdersDTO createOrder(OrdersDTO ordersDTO) {
        // 1. 生成订单ID
        ResponseResult rr = this.idGeneratorClient.getNextId();
        if (rr.getCode() != 1) {
            throw new RuntimeException("订单ID生成失败");
        }
        Long orderId = Long.parseLong(rr.getData().toString());
        ordersDTO.setOrderId(orderId);

        // 2. 设置订单默认状态为待支付(1)
        if (ordersDTO.getOrderStatus() == null) {
            ordersDTO.setOrderStatus(1);
        }

        // 3. 设置创建和更新时间
        ordersDTO.setUpdateTime(LocalDateTime.now());

        // 4. 保存订单主表
        Orders order = new Orders();
        BeanUtils.copyProperties(ordersDTO, order);
        int result = this.ordersMapper.insert(order);
        if (result <= 0) {
            throw new RuntimeException("订单创建失败");
        }

        // 5. 保存订单商品明细
        if (ordersDTO.getItems() != null && !ordersDTO.getItems().isEmpty()) {
            for (OrderItemsDTO itemDTO : ordersDTO.getItems()) {
                ResponseResult itemRr = this.idGeneratorClient.getNextId();
                if (itemRr.getCode() != 1) {
                    throw new RuntimeException("订单明细ID生成失败");
                }
                Long itemId = Long.parseLong(itemRr.getData().toString());
                itemDTO.setOrderItemId(itemId);
                itemDTO.setOrderId(orderId);

                OrderItems item = new OrderItems();
                BeanUtils.copyProperties(itemDTO, item);
                int itemResult = this.orderItemsMapper.insert(item);
                if (itemResult <= 0) {
                    throw new RuntimeException("订单明细保存失败");
                }
            }
        }

        // 6. 返回完整的订单信息
        OrdersDTO resultDTO = new OrdersDTO();
        BeanUtils.copyProperties(order, resultDTO);
        resultDTO.setItems(ordersDTO.getItems());
        return resultDTO;
    }

    /**
     * 根据用户ID和订单状态查询订单
     * @param userId 用户ID
     * @param orderStatus 订单状态
     * @return 订单DTO列表
     */
    @Override
    public List<OrdersDTO> getOrdersByUserAndStatus(Long userId, Integer orderStatus) {
        LambdaQueryWrapper<Orders> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Orders::getUserId, userId);
        if (orderStatus != null) {
            queryWrapper.eq(Orders::getOrderStatus, orderStatus);
        }
        queryWrapper.orderByDesc(Orders::getUpdateTime);

        List<Orders> orders = this.ordersMapper.selectList(queryWrapper);
        return orders.stream().map(order -> {
            OrdersDTO dto = new OrdersDTO();
            BeanUtils.copyProperties(order, dto);

            // 查询订单明细
            List<OrderItemsDTO> itemDTOs = orderItemsService.getItemsByOrderId(order.getOrderId());
            dto.setItems(itemDTOs);

            // 计算商品总数和总金额
            if (itemDTOs != null && !itemDTOs.isEmpty()) {
                int count = itemDTOs.stream().mapToInt(OrderItemsDTO::getQuantity).sum();
                double total = itemDTOs.stream()
                        .mapToDouble(item -> item.getPrice() * item.getQuantity())
                        .sum();

                dto.setItemCount(count);
                dto.setTotalAmount(total);
            } else {
                dto.setItemCount(0);
                dto.setTotalAmount(0.0);
            }

            return dto;
        }).collect(Collectors.toList());
    }

    /**
     * 分页查询订单
     * @param queryVO 查询参数，包含用户ID、订单状态、订单ID、时间范围、排序方式等
     * @return 订单DTO的分页结果
     */
    @Override
    public IPage<OrdersDTO> listOrdersPaged(OrdersQueryVO queryVO) {
        // 创建MyBatis-Plus分页对象
        Page<Orders> page = new Page<>(queryVO.getCurrent(), queryVO.getSize());

        // 构建查询条件
        LambdaQueryWrapper<Orders> queryWrapper = new LambdaQueryWrapper<>();

        // 根据用户ID查询
        if (queryVO.getUserId() != null) {
            queryWrapper.eq(Orders::getUserId, queryVO.getUserId());
        }

        // 根据订单状态查询
        if (queryVO.getOrderStatus() != null) {
            queryWrapper.eq(Orders::getOrderStatus, queryVO.getOrderStatus());
        }

        // 根据订单ID查询
        if (queryVO.getOrderId() != null) {
            queryWrapper.eq(Orders::getOrderId, queryVO.getOrderId());
        }

        // 时间范围查询
        if (queryVO.getStartTime() != null && queryVO.getEndTime() != null) {
            queryWrapper.between(Orders::getUpdateTime, queryVO.getStartTime(), queryVO.getEndTime());
        }

        // 处理排序
        if (StringUtils.hasText(queryVO.getSortField())) {
            boolean isAsc = !"desc".equalsIgnoreCase(queryVO.getSortOrder());
            switch (queryVO.getSortField().toLowerCase()) {
                case "updatetime":
                    queryWrapper.orderBy(true, isAsc, Orders::getUpdateTime);
                    break;
                case "orderid":
                    queryWrapper.orderBy(true, isAsc, Orders::getOrderId);
                    break;
                case "paymenttime":
                    queryWrapper.orderBy(true, isAsc, Orders::getPaymentTime);
                    break;
                default:
                    // 默认按更新时间降序
                    queryWrapper.orderByDesc(Orders::getUpdateTime);
                    break;
            }
        } else {
            // 默认排序
            queryWrapper.orderByDesc(Orders::getUpdateTime);
        }

        // 执行分页查询
        IPage<Orders> ordersPage = ordersMapper.selectPage(page, queryWrapper);

        // 将实体分页结果转换为DTO分页结果
        return ordersPage.convert(order -> {
            OrdersDTO dto = new OrdersDTO();
            BeanUtils.copyProperties(order, dto);

            // 查询订单项
            List<OrderItemsDTO> items = orderItemsService.getItemsByOrderId(order.getOrderId());
            dto.setItems(items);

            // 可以添加其他信息，如地址信息等
            // dto.setAddress(addressService.getAddressById(order.getAddressId()));

            return dto;
        });
    }

    /**
     * 获取订单详情
     * @param orderId 订单ID
     * @return 订单DTO
     */
    @Override
    public OrdersDTO getOrderDetail(Long orderId) {
        // 1. 查询订单主表
        Orders order = ordersMapper.selectById(orderId);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }

        // 2. 转换为DTO
        OrdersDTO dto = new OrdersDTO();
        BeanUtils.copyProperties(order, dto);

        // 3. 查询订单明细
        List<OrderItemsDTO> itemDTOs = orderItemsService.getItemsByOrderId(order.getOrderId());
        dto.setItems(itemDTOs);

        // 4. 计算商品总数和总金额
        if (itemDTOs != null && !itemDTOs.isEmpty()) {
            int count = itemDTOs.stream().mapToInt(OrderItemsDTO::getQuantity).sum();
            double total = itemDTOs.stream()
                    .mapToDouble(item -> item.getPrice() * item.getQuantity())
                    .sum();

            dto.setItemCount(count);
            dto.setTotalAmount(total);
        } else {
            dto.setItemCount(0);
            dto.setTotalAmount(0.0);
        }

        return dto;
    }

    /**
     * 取消订单
     * @param orderId 订单ID
     * @return 操作结果
     */
    @Override
    @Transactional
    public boolean cancelOrder(Long orderId) {
        // 1. 查询订单
        Orders order = ordersMapper.selectById(orderId);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }

        // 2. 检查订单状态(只有待支付和已支付待发货的订单可以取消)
        if (order.getOrderStatus() != 1 && order.getOrderStatus() != 2) {
            throw new RuntimeException("当前订单状态不允许取消");
        }

        // 3. 更新订单状态为取消(0)
        order.setOrderStatus(0);
        order.setUpdateTime(LocalDateTime.now());
        return ordersMapper.updateById(order) > 0;
    }

    /**
     * 确认收货
     * @param orderId 订单ID
     * @return 操作结果
     */
    @Override
    @Transactional
    public boolean confirmReceipt(Long orderId) {
        // 1. 查询订单
        Orders order = ordersMapper.selectById(orderId);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }

        // 2. 检查订单状态(只有已发货的订单可以确认收货)
        if (order.getOrderStatus() != 3) {
            throw new RuntimeException("当前订单状态不允许确认收货");
        }

        // 3. 更新订单状态为已签收(4)
        order.setOrderStatus(4);
        order.setUpdateTime(LocalDateTime.now());
        return ordersMapper.updateById(order) > 0;
    }

    /**
     * 申请售后
     * @param orderId 订单ID
     * @param reason 售后原因
     * @return 操作结果
     */
    @Override
    @Transactional
    public boolean applyAfterSale(Long orderId, String reason) {
        // 1. 查询订单
        Orders order = ordersMapper.selectById(orderId);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }

        // 2. 检查订单状态(只有已签收和订单完成的可以申请售后)
        if (order.getOrderStatus() != 4 && order.getOrderStatus() != 5) {
            throw new RuntimeException("当前订单状态不允许申请售后");
        }

        // 3. 更新订单状态为申请售后(6)
        order.setOrderStatus(6);
        order.setUpdateTime(LocalDateTime.now());
        order.setRemark(reason); // 保存售后原因
        return ordersMapper.updateById(order) > 0;
    }

    /**
     * 获取用户订单各状态数量统计
     * @param userId 用户ID
     * @return 包含各状态订单数量的Map
     */
    @Override
    @Transactional
    public Map<Integer, Long> getOrderStatusCounts(Long userId) {
        // 使用自定义的mapper方法
        List<Map<String, Object>> statusCounts = ordersMapper.countByStatusGroup(userId);

        // 转换为Map并确保所有状态都有值
        Map<Integer, Long> result = statusCounts.stream()
                .collect(Collectors.toMap(
                        map -> (Integer) map.get("status"),
                        map -> (Long) map.get("count")
                ));

        // 初始化所有可能的状态
        for (int status : Arrays.asList(0, 1, 2, 3, 4, 5, 6)) {
            result.putIfAbsent(status, 0L);
        }

        return result;
    }

    /**
     * 检查订单状态
     * @param orderId 订单ID
     * @return true 如果已支付，否则false
     */
    public boolean checkOrderPaid(Long orderId) {
        // 从数据库查询订单状态
        Orders order = ordersMapper.selectById(orderId);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }

        // 假设2表示已支付
        return order.getOrderStatus() == 2;
    }

    /**
     * 更新订单状态
     * @param orderId 订单ID
     * @param newStatus 新状态
     * @return 是否更新成功
     */
    @Override
    @Transactional
    public boolean updateOrderStatus(Long orderId, Integer newStatus) {
        // 1. 查询订单
        Orders order = ordersMapper.selectById(orderId);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }

        // 2. 验证状态转换是否合法
        if (!isValidStatusTransition(order.getOrderStatus(), newStatus)) {
            throw new RuntimeException("非法的订单状态转换");
        }

        // 3. 更新订单状态
        order.setOrderStatus(newStatus);
        order.setUpdateTime(LocalDateTime.now());

        // 4. 根据状态设置特定时间字段
        if (newStatus == 2) { // 已支付
            order.setPaymentTime(LocalDateTime.now());
        } else if (newStatus == 3) { // 已发货
            order.setShippingTime(LocalDateTime.now());
        }

        return ordersMapper.updateById(order) > 0;
    }

    /**
     * 验证订单状态转换是否合法
     * @param currentStatus 当前状态
     * @param newStatus 新状态
     * @return 是否合法
     */
    private boolean isValidStatusTransition(Integer currentStatus, Integer newStatus) {
        // 定义合法的状态转换规则
        Map<Integer, List<Integer>> validTransitions = new HashMap<>();
        validTransitions.put(0, Arrays.asList()); // 已取消状态不能转换
        validTransitions.put(1, Arrays.asList(0, 2)); // 待支付可以转为已取消或已支付
        validTransitions.put(2, Arrays.asList(0, 3)); // 已支付可以转为已取消或已发货
        validTransitions.put(3, Arrays.asList(0, 4)); // 已发货可以转为已取消或已签收
        validTransitions.put(4, Arrays.asList(5, 6)); // 已签收可以转为已完成或申请售后
        validTransitions.put(5, Arrays.asList()); // 已完成状态不能转换
        validTransitions.put(6, Arrays.asList(5)); // 申请售后可以转为已完成

        List<Integer> allowedTransitions = validTransitions.get(currentStatus);
        return allowedTransitions != null && allowedTransitions.contains(newStatus);
    }
}